// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Subsystems/WorldSubsystem.h" // 包含世界子系统头文件

#include "LyraAudioMixEffectsSubsystem.generated.h" // 包含生成的头文件

#define UE_API LYRAGAME_API // 定义UE_API宏

class FSubsystemCollectionBase;
class UObject;
class USoundControlBus;
class USoundControlBusMix;
class USoundEffectSubmixPreset;
class USoundSubmix;
class UWorld;

USTRUCT()
struct FLyraAudioSubmixEffectsChain
{
	GENERATED_BODY()

	// 应用子混音效果链覆盖的子混音
	UPROPERTY(Transient)
	TObjectPtr<USoundSubmix> Submix = nullptr; // 子混音对象指针

	// 子混音效果链覆盖（效果按数组索引顺序处理）
	UPROPERTY(Transient)
	TArray<TObjectPtr<USoundEffectSubmixPreset>> SubmixEffectChain; // 子混音效果预设对象指针数组
};

/**
 * 此子系统旨在自动启用默认和用户控制总线混合
 * 以检索先前保存的用户设置并将其应用于激活的用户混合。
 * 此外，此子系统将根据用户对HDR音频的偏好自动应用HDR/LDR音频子混音效果链覆盖。
 * 子混音效果链覆盖在Lyra音频设置中定义。
 */
UCLASS(MinimalAPI)
class ULyraAudioMixEffectsSubsystem : public UWorldSubsystem
{
	GENERATED_BODY()

public:
	// USubsystem 实现开始
	/**
	 * 初始化子系统
	 * @param Collection 子系统集合基类引用
	 */
	UE_API virtual void Initialize(FSubsystemCollectionBase& Collection) override;
	/**
	 * 反初始化子系统
	 */
	UE_API virtual void Deinitialize() override;
	// USubsystem 实现结束

	/**
	 * 判断是否应创建子系统
	 * @param Outer 外部对象
	 * @return 是否应创建子系统
	 */
	UE_API virtual bool ShouldCreateSubsystem(UObject* Outer) const override;

	/** 在所有UWorldSubsystem初始化后调用一次 */
	UE_API virtual void PostInitialize() override;

	/** 在世界准备好开始游戏玩法时调用，在游戏模式转换到正确状态并在所有Actor上调用BeginPlay之前 */
	UE_API virtual void OnWorldBeginPlay(UWorld& InWorld) override;

	/** 设置是否应用HDR音频子混音效果链覆盖设置 */
	UE_API void ApplyDynamicRangeEffectsChains(bool bHDRAudio);
	
protected:
	/**
	 * 加载屏幕状态改变时调用
	 * @param bShowingLoadingScreen 是否显示加载屏幕
	 */
	UE_API void OnLoadingScreenStatusChanged(bool bShowingLoadingScreen);
	/**
	 * 应用或移除加载屏幕混合
	 * @param bWantsLoadingScreenMix 是否想要加载屏幕混合
	 */
	UE_API void ApplyOrRemoveLoadingScreenMix(bool bWantsLoadingScreenMix);
	
	/** 在确定是否创建此子系统时调用 */
	UE_API virtual bool DoesSupportWorldType(const EWorldType::Type WorldType) const override;

	// 从Lyra音频设置中检索的默认声音控制总线混合
	UPROPERTY(Transient)
	TObjectPtr<USoundControlBusMix> DefaultBaseMix = nullptr; // 默认基础混合

	// 从Lyra音频设置中检索的加载屏幕声音控制总线混合
	UPROPERTY(Transient)
	TObjectPtr<USoundControlBusMix> LoadingScreenMix = nullptr; // 加载屏幕混合

	// 从Lyra音频设置中检索的用户声音控制总线混合
	UPROPERTY(Transient)
	TObjectPtr<USoundControlBusMix> UserMix = nullptr; // 用户混合

	// 从Lyra音频设置中检索的总体声音控制总线，并链接到LyraSettingsLocal中的UI和游戏设置
	UPROPERTY(Transient)
	TObjectPtr<USoundControlBus> OverallControlBus = nullptr; // 总体控制总线

	// 从Lyra音频设置中检索的音乐声音控制总线，并链接到LyraSettingsLocal中的UI和游戏设置
	UPROPERTY(Transient)
	TObjectPtr<USoundControlBus> MusicControlBus = nullptr; // 音乐控制总线

	// 从Lyra音频设置中检索的音效声音控制总线，并链接到LyraSettingsLocal中的UI和游戏设置
	UPROPERTY(Transient)
	TObjectPtr<USoundControlBus> SoundFXControlBus = nullptr; // 音效控制总线

	// 从Lyra音频设置中检索的对话声音控制总线，并链接到LyraSettingsLocal中的UI和游戏设置
	UPROPERTY(Transient)
	TObjectPtr<USoundControlBus> DialogueControlBus = nullptr; // 对话控制总线

	// 从Lyra音频设置中检索的语音聊天声音控制总线，并链接到LyraSettingsLocal中的UI和游戏设置
	UPROPERTY(Transient)
	TObjectPtr<USoundControlBus> VoiceChatControlBus = nullptr; // 语音聊天控制总线

	// 当HDR音频打开时应用的子混音效果链覆盖
	UPROPERTY(Transient)
	TArray<FLyraAudioSubmixEffectsChain> HDRSubmixEffectChain; // HDR子混音效果链数组

	// 当HDR音频关闭时应用的子混音效果链覆盖
	UPROPERTY(Transient)
	TArray<FLyraAudioSubmixEffectsChain> LDRSubmixEffectChain; // LDR子混音效果链数组

	bool bAppliedLoadingScreenMix = false; // 是否已应用加载屏幕混合
};

#undef UE_API // 取消定义UE_API宏